package cn.edu.xmu.oomall.aftersale.service;

import cn.edu.xmu.oomall.aftersale.dao.AfterSaleDao;
import cn.edu.xmu.oomall.aftersale.microservice.*;
import cn.edu.xmu.oomall.aftersale.microservice.vo.SimpleOrderItemVo;
import cn.edu.xmu.oomall.aftersale.microservice.vo.SimplePaymentVo;
import cn.edu.xmu.oomall.aftersale.model.bo.Aftersale;
import cn.edu.xmu.oomall.aftersale.model.bo.AftersaleState;
import cn.edu.xmu.oomall.aftersale.model.vo.*;
import cn.edu.xmu.oomall.core.model.VoObject;
import cn.edu.xmu.oomall.core.util.JacksonUtil;
import cn.edu.xmu.oomall.core.util.ReturnNo;
import cn.edu.xmu.oomall.core.util.ReturnObject;
import cn.edu.xmu.privilegegateway.annotation.util.InternalReturnObject;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

import static cn.edu.xmu.privilegegateway.annotation.util.Common.cloneVo;

/**
 * @author X-Raymond
 * @date 2021/12/9
 */
@Service
public class AfterSaleService {

    @Autowired
    AfterSaleDao afterSaleDao;

    @Autowired
    private CustomerService customerService;

    @Autowired
    private RegionService regionService;

    @Autowired
    private OrderService orderService;

    /**
     * 获得售后单的所有状态
     *
     * @return ReturnObject<List < Map < String, Object>>>
     */
    public ReturnObject getAllState() {
        List<StateVo> stateVos = new ArrayList<>();
        for (AftersaleState state : AftersaleState.values()) {
            StateVo stateVo = new StateVo(state.getCode(), state.getDescription());
            stateVos.add(stateVo);
        }
        return new ReturnObject(stateVos);
    }

    /**
     * @param beginTime
     * @param state
     * @param endTime
     * @param page
     * @param pageSize  查询自己的售后单
     * @return ReturnObject<PageInfo < VoObject>>
     */

    @Transactional(readOnly = true, rollbackFor = Exception.class)
    public ReturnObject<PageInfo<VoObject>> getOwnAftersales(Long id, LocalDateTime beginTime, Integer state, LocalDateTime endTime, Integer page, Integer pageSize) {
        //添加查询条件
        ReturnObject returnObject = afterSaleDao.getOwnAftersale(id, beginTime, state, endTime, page, pageSize);
        return returnObject;
    }

    /**
     * 管理员根据id查看对应的售后
     *
     * @param id
     * @return
     */
    @Transactional(readOnly = true)
    public ReturnObject getAftersalesById(Long id) {
        ReturnObject returnObject = afterSaleDao.getAftersalesById(id);
        if (!returnObject.getCode().equals(ReturnNo.OK)) {
            return returnObject;
        }
        Aftersale aftersale = (Aftersale) returnObject.getData();
        InternalAftersalesVo internalAftersalesVo = cloneVo(aftersale, InternalAftersalesVo.class);
        return new ReturnObject(internalAftersalesVo);
    }

    /**
     * 管理员查看售后
     *
     * @param shopId
     * @param beginTime
     * @param state
     * @param endTime
     * @param type
     * @param pageSize
     * @param page
     * @return
     */
    @Transactional(readOnly = true)
    public ReturnObject<PageInfo<VoObject>> getAftersales(Long shopId, LocalDateTime beginTime, Integer state, LocalDateTime endTime, Integer type, Integer pageSize, Integer page) {

        ReturnObject returnObject = afterSaleDao.getAllAftersale(shopId, beginTime, endTime, state, type, page, pageSize);
        return returnObject;
    }

    /**
     * 根据id查看自己的售后
     *
     * @param userId
     * @param id
     * @return
     */
    public ReturnObject getOwnAftersalesById(Long userId, Long id) {
        ReturnObject returnObject = afterSaleDao.getAftersalesById(id);
        if (returnObject.getData() == null) {
            return returnObject;
        }
        Aftersale aftersale = (Aftersale) returnObject.getData();
        if (!userId.equals(aftersale.getCustomerId())) {
            return new ReturnObject(ReturnNo.RESOURCE_ID_OUTSCOPE);
        }
        System.out.println(aftersale.getCustomerId());
        var internalRet1 = customerService.getSimpleCustomerById(aftersale.getCustomerId());
        if (!internalRet1.getErrno().equals(ReturnNo.OK.getCode())) {
            return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR, internalRet1.getErrmsg());
        }
        var internalRet2 = regionService.getSimpleRegionById(aftersale.getRegionId());
        if (!internalRet2.getErrno().equals(ReturnNo.OK.getCode())) {
            return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR, internalRet2.getErrmsg());
        }
        SimpleCustomerVo simpleCustomerVo = internalRet1.getData();
        SimpleRegionVo simpleRegionVo = internalRet2.getData();
        AftersaleRetVo aftersaleRetVo = cloneVo(aftersale, AftersaleRetVo.class);
        aftersaleRetVo.setCustomer(simpleCustomerVo);
        aftersaleRetVo.setRegion(simpleRegionVo);
        return new ReturnObject(aftersaleRetVo);
    }

    /**
     * 根据id修改售后单
     *
     * @param userId
     * @param userName
     * @param id
     * @param aftersaleModifyVo
     * @return
     */
    public ReturnObject modifyOwnAftersaleById(Long userId, String userName, Long id, AftersaleModifyVo aftersaleModifyVo) {
        Aftersale aftersale = cloneVo(aftersaleModifyVo, Aftersale.class);
        Aftersale x = (Aftersale) afterSaleDao.getAftersalesById(id).getData();
        if (x == null) {
            return new ReturnObject(ReturnNo.RESOURCE_ID_NOTEXIST);
        }
        if (!(x.getState().byteValue() == 0 || x.getState().byteValue() == 1)) {
            return new ReturnObject(ReturnNo.STATENOTALLOW);
        }
        if (!x.getCustomerId().equals(userId)) {
            return new ReturnObject(ReturnNo.RESOURCE_ID_OUTSCOPE);
        }
        aftersale.setModifierName(userName);
        aftersale.setModifierId(userId);
        ReturnObject returnObject = afterSaleDao.modifyAftersalesById(id, aftersale);
        return returnObject;
    }

    /**
     * 根据商店id和id查询售后单
     *
     * @param shopId
     * @param id
     * @return
     */
    public ReturnObject getAftersalesByShopIdAndId(Long shopId, Long id) {
        ReturnObject returnObject = afterSaleDao.getAftersalesByShopIdAndId(shopId, id);
        if (returnObject.getData() == null) {
            return returnObject;
        }
        Aftersale aftersale = (Aftersale) returnObject.getData();
        if (!aftersale.getShopId().equals(shopId)) {
            return new ReturnObject(ReturnNo.RESOURCE_ID_OUTSCOPE);
        }
        var internalRet1 = customerService.getSimpleCustomerById(aftersale.getCustomerId());
        if (!internalRet1.getErrno().equals(ReturnNo.OK.getCode())) {
            return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR, internalRet1.getErrmsg());
        }
        var internalRet2 = regionService.getSimpleRegionById(aftersale.getRegionId());
        if (!internalRet2.getErrno().equals(ReturnNo.OK.getCode())) {
            return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR, internalRet2.getErrmsg());
        }
        SimpleCustomerVo simpleCustomerVo = internalRet1.getData();
        SimpleRegionVo simpleRegionVo = internalRet2.getData();
        AftersaleRetVo aftersaleRetVo = cloneVo(aftersale, AftersaleRetVo.class);
        aftersaleRetVo.setCustomer(simpleCustomerVo);
        aftersaleRetVo.setRegion(simpleRegionVo);
        return new ReturnObject(aftersaleRetVo);
    }

    /**
     * 买家发货，填写运费单
     *
     * @param userId
     * @param userName
     * @param id
     * @param customerLogSnVo
     * @return
     */
    public ReturnObject addUserLogSn(Long userId, String userName, Long id, CustomerLogSnVo customerLogSnVo) {
        Aftersale x = (Aftersale) afterSaleDao.getAftersalesById(id).getData();
        if (x == null) {
            return new ReturnObject(ReturnNo.RESOURCE_ID_NOTEXIST);
        }
        if (x.getState().byteValue() != 1) {
            return new ReturnObject(ReturnNo.STATENOTALLOW);
        }
        if (!x.getCustomerId().equals(userId)) {
            return new ReturnObject(ReturnNo.RESOURCE_ID_OUTSCOPE);
        }
        x.setCustomerLogSn(customerLogSnVo.getCustomerLogSn());
        x.setState(AftersaleState.UDELIVER.getCode().byteValue());
        x.setModifierName(userName);
        x.setModifierId(userId);
        ReturnObject returnObject = afterSaleDao.modifyAftersalesById(id, x);
        return returnObject;
    }

    /**
     * 用户确认结束
     *
     * @param userId
     * @param userName
     * @param id
     * @return
     */
    public ReturnObject userConfirmEnd(Long userId, String userName, Long id) {
        Aftersale x = (Aftersale) afterSaleDao.getAftersalesById(id).getData();
        if (x == null) {
            return new ReturnObject(ReturnNo.RESOURCE_ID_NOTEXIST);
        }
        if (!(x.getState().byteValue() == AftersaleState.SDELIVER.getCode() || x.getState().byteValue() == AftersaleState.WREFUND.getCode())) {
            return new ReturnObject(ReturnNo.STATENOTALLOW);
        }
        if (!x.getCustomerId().equals(userId)) {
            return new ReturnObject(ReturnNo.RESOURCE_ID_OUTSCOPE);
        }
        x.setState(AftersaleState.FINISH.getCode().byteValue());
        x.setModifierName(userName);
        x.setModifierId(userId);
        ReturnObject returnObject = afterSaleDao.modifyAftersalesById(id, x);
        return returnObject;
    }

    /**
     * 管理员确认售后单
     *
     * @param shopId
     * @param id
     * @param shopConfirmVo
     * @return
     */
    public ReturnObject shopConfirmAftersales(Long userId, String userName, Long shopId, Long id, ShopConfirmVo shopConfirmVo) {
        Aftersale aftersale = cloneVo(shopConfirmVo, Aftersale.class);
        Aftersale x = (Aftersale) afterSaleDao.getAftersalesById(id).getData();
        if (x == null) {
            return new ReturnObject(ReturnNo.RESOURCE_ID_NOTEXIST);
        }
        if (x.getState().byteValue() != AftersaleState.BEGIN.getCode()) {
            return new ReturnObject(ReturnNo.STATENOTALLOW);
        }
        if (!x.getShopId().equals(shopId)) {
            return new ReturnObject(ReturnNo.RESOURCE_ID_OUTSCOPE);
        }
        if (shopConfirmVo.getConfirm()) {
            aftersale.setState(AftersaleState.WUDELIVER.getCode().byteValue());
        } else {
            aftersale.setState(AftersaleState.CANCEL.getCode().byteValue());
        }
        aftersale.setModifierId(userId);
        aftersale.setModifierName(userName);
        ReturnObject returnObject = afterSaleDao.modifyAftersalesById(id, aftersale);
        return returnObject;
    }

    /**
     * 商家验收
     *
     * @param userId
     * @param userName
     * @param shopId
     * @param id
     * @param shopReceiveVo
     * @return
     */
    public ReturnObject shopReceiveAftersales(Long userId, String userName, Long shopId, Long id, ShopReceiveVo shopReceiveVo) {
        Aftersale aftersale = cloneVo(shopReceiveVo, Aftersale.class);
        Aftersale x = (Aftersale) afterSaleDao.getAftersalesById(id).getData();
        if (x == null) {
            return new ReturnObject(ReturnNo.RESOURCE_ID_NOTEXIST);
        }
        if (x.getState().byteValue() != AftersaleState.UDELIVER.getCode()) {
            return new ReturnObject(ReturnNo.STATENOTALLOW);
        }
        if (!x.getShopId().equals(shopId)) {
            return new ReturnObject(ReturnNo.RESOURCE_ID_OUTSCOPE);
        }
        int returnd = 0, changed = 1, fixed = 2;
        if (shopReceiveVo.getConfirm()) {
            if (x.getType() == returnd) {
                aftersale.setState(AftersaleState.WREFUND.getCode().byteValue());
            } else if (x.getType() == changed) {
                aftersale.setState(AftersaleState.SDELIVER.getCode().byteValue());
            } else if (x.getType() == fixed) {
                aftersale.setState(AftersaleState.WPAY.getCode().byteValue());
            }
        } else {
            aftersale.setState(AftersaleState.WUDELIVER.getCode().byteValue());
        }
        aftersale.setModifierId(userId);
        aftersale.setModifierName(userName);
        ReturnObject returnObject = afterSaleDao.modifyAftersalesById(id, aftersale);
        return returnObject;
    }

    /**
     * 商家发货
     *
     * @param userId
     * @param userName
     * @param shopId
     * @param id
     * @param shopLogSnVo
     * @return
     */
    public ReturnObject shopDeliverAftersales(Long userId, String userName, Long shopId, Long id, ShopLogSnVo shopLogSnVo) {
        Aftersale aftersale = cloneVo(shopLogSnVo, Aftersale.class);
        Aftersale x = (Aftersale) afterSaleDao.getAftersalesById(id).getData();
        if (x == null) {
            return new ReturnObject(ReturnNo.RESOURCE_ID_NOTEXIST);
        }
        if (x.getState().byteValue() != AftersaleState.WSDELIVER.getCode()) {
            return new ReturnObject(ReturnNo.STATENOTALLOW);
        }
        if (!x.getShopId().equals(shopId)) {
            return new ReturnObject(ReturnNo.RESOURCE_ID_OUTSCOPE);
        }
        aftersale.setModifierId(userId);
        aftersale.setModifierName(userName);
        ReturnObject returnObject = afterSaleDao.modifyAftersalesById(id, aftersale);
        return returnObject;
    }

    /**
     * 用户新增售后单
     *
     * @param userName
     * @param userId
     * @param orderItemId
     * @param aftersaleAddVo
     * @return
     */
    public ReturnObject userAddAftersales(String userName, Long userId, Long orderItemId, AftersaleAddVo aftersaleAddVo) {
        Aftersale aftersale = cloneVo(aftersaleAddVo, Aftersale.class);
        try {
            var internalRet = orderService.getSimpleOrderItemById(orderItemId);
            if (!internalRet.getErrno().equals(ReturnNo.OK.getCode())) {
                return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR, internalRet.getErrmsg());
            }
            SimpleOrderItemVo simpleOrderItemVo = internalRet.getData();
            aftersale.setState(AftersaleState.BEGIN.getCode().byteValue());
            aftersale.setOrderId(simpleOrderItemVo.getOrderId());
            aftersale.setShopId(simpleOrderItemVo.getShopId());
            aftersale.setOrderItemId(orderItemId);
            aftersale.setCustomerId(userId);
            aftersale.setCreatorName(userName);
            aftersale.setCreatorId(userId);
        } catch (Exception e) {
            e.printStackTrace();
        }
        ReturnObject returnObject = afterSaleDao.addAftersales(aftersale);
        return returnObject;
    }

    /**
     * 用户逻辑删除或取消售后单
     *
     * @param userId
     * @param id
     * @return
     */
    public ReturnObject userLogicDeleteAftersalesById(Long userId, Long id) {
        Aftersale aftersale = (Aftersale) afterSaleDao.getAftersalesById(id).getData();
        if (aftersale == null) {
            return new ReturnObject(ReturnNo.RESOURCE_ID_NOTEXIST);
        }
        System.out.println(aftersale.getCustomerId());
        System.out.println(userId);
        if (!aftersale.getCustomerId().equals(userId)) {
            return new ReturnObject(ReturnNo.RESOURCE_ID_OUTSCOPE);
        }
        if (aftersale.getState().byteValue() != AftersaleState.BEGIN.getCode()) {
            if (aftersale.getState().byteValue() != AftersaleState.WUDELIVER.getCode()) {
                if (aftersale.getState().byteValue() != AftersaleState.FINISH.getCode()) {
                    return new ReturnObject(ReturnNo.STATENOTALLOW);
                }
            }
        }
        if (aftersale.getState().byteValue() != AftersaleState.FINISH.getCode()) {
            aftersale.setState(AftersaleState.CANCEL.getCode().byteValue());
        } else {
            return afterSaleDao.logicDeleteAftersalesById(id);
        }
        ReturnObject returnObject = afterSaleDao.modifyAftersalesById(id, aftersale);
        return returnObject;
    }

    public ReturnObject getPaymentBydId(Long userId, String userName, Long id) {
        Aftersale aftersale = (Aftersale) afterSaleDao.getAftersalesById(id).getData();
        if (!userId.equals(aftersale.getCustomerId())) {
            return new ReturnObject(ReturnNo.RESOURCE_ID_OUTSCOPE);
        }
        var internalRet = orderService.getPaymentByOrderId(aftersale.getOrderId());
        if (!internalRet.getErrno().equals(ReturnNo.OK.getCode())) {
            return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR, internalRet.getErrmsg());
        }
        SimplePaymentVo simplePaymentVo = internalRet.getData();
        return new ReturnObject(simplePaymentVo);
    }
}
